package switchviz.network.netswitch;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import switchviz.core.ResourceManager;
import switchviz.gui.component.IXMLFilter;
import switchviz.gui.component.XMLTree;
import switchviz.gui.component.XMLTreeNode;

public class SwitchTree extends XMLTree
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 3948432698157863327L;
	public static final String SWITCHNODE = "switch";
	public static final String SWITCHNAME = "name";
	public static final String SWITCHADDRESS = "address";
	public static final String SWITCHCOMMUNITY = "community";
	public static final String SWITCHPORT= "port";
	public static final String SWITCHDESCRIPTION = "description";
	public static final String SWITCHTIMEOUT = "timeout";
	public static final String SWITCHMAXRETRIES = "maxretries";
	public static final String SWITCHPDUCAPACITY = "pducapacity";
	public static final String SWITCHPORTCOUNT = "switchportcount";
	public static final String SWITCHIFPORT = "switchifport";
	public static final String SWITCHTYPE = "switchtype";
	
	public SwitchTree(File xmlfile, IXMLFilter xmlfilter) throws JDOMException, IOException 
	{
		super(xmlfile, xmlfilter);
		this.setPreferredSize(new Dimension(400, 400));
		this.getTree().setRootVisible(false);
		this.setLeafNodeIcon(ResourceManager.getInstance().getImageIconSwitch());
	}
	
	public static List<SwitchDataModel> getSwitchList() throws JDOMException, IOException
	{
		ArrayList<SwitchDataModel> switchlist = new ArrayList<SwitchDataModel>();
		Iterator<?> it = getSwitchIterator();
		while(it.hasNext())
		{
			Element snode = (Element)it.next();
			switchlist.add(createSwitchModel(snode));
		}
		return switchlist;
	}
	
	public static SwitchDataModel getSwitchModel(String switchname) throws JDOMException, IOException
	{
		Iterator<?> it = getSwitchIterator();
		while(it.hasNext())
		{
			Element snode = (Element)it.next();
			if (snode.getChildText(SWITCHNAME).equals(switchname))
				return createSwitchModel(snode);
		}
		if(logger.isDebugEnabled())
			logger.debug("Switch with name " + switchname + " could not be resolved");
		return null;
	}

	private static Iterator<?> getSwitchIterator() throws JDOMException, IOException
	{
		SAXBuilder parser = new SAXBuilder();
		Document doc = parser.build(ResourceManager.getInstance().getSwitchConfigurationFile());
		return doc.getRootElement().getChildren(SWITCHNODE).iterator();
	}
	
	@SuppressWarnings("unchecked")
	public static SwitchDataModel createSwitchModel(Element snode)
	{
		SwitchDataModel sdm = new SwitchDataModel();
		
		sdm.setName(snode.getChildText(SWITCHNAME));
		sdm.setAddress(snode.getChildText(SWITCHADDRESS));
		sdm.setPort(Integer.valueOf(snode.getChildText(SWITCHPORT)));
		sdm.setCommunity(snode.getChildText(SWITCHCOMMUNITY));
		sdm.setDescription(snode.getChildTextNormalize(SWITCHDESCRIPTION));
		sdm.setTimeout(Long.valueOf(snode.getChildText(SWITCHTIMEOUT)));
		sdm.setMaxRetries(Integer.valueOf(snode.getChildText(SWITCHMAXRETRIES)));
		sdm.setPDUCapacity(Integer.valueOf(snode.getChildText(SWITCHPDUCAPACITY)));
		
		if(snode.getChild(SWITCHTYPE) != null)
			sdm.setType(snode.getChildText(SWITCHTYPE));
		
	    if(snode.getChild(SWITCHPORTCOUNT) != null)
	    {
			List<String> switchport = new ArrayList<String>();
	    	Iterator<Element> it = snode.getChild(SWITCHPORTCOUNT).getChildren(SWITCHIFPORT).iterator();
	    	while(it.hasNext())
	    		switchport.add(it.next().getText());
	    	
	    	sdm.setPortList(switchport);
	    }
		
		return sdm;
	}
	public void addSwitchNode(String name) throws Exception
	{
		XMLTreeNode switchnode = new XMLTreeNode(name, new Element(SWITCHNODE));
		Element switchname =  new Element(SWITCHNAME).setText(name);
		Element switchaddress = new Element(SWITCHADDRESS);
		Element switchport = new Element(SWITCHPORT).setText("161");
		Element switchdescription = new Element(SWITCHDESCRIPTION);
		Element switchcommunity = new Element(SWITCHCOMMUNITY).setText("public");
		Element switchtimeout = new Element(SWITCHTIMEOUT).setText("10000");
		Element switchmaxretries = new Element(SWITCHMAXRETRIES).setText("0");
		Element switchpducapacity = new Element(SWITCHPDUCAPACITY).setText("45");
		Element switchportlist = new Element(SWITCHPORTCOUNT);
		Element switchtype = new Element(SWITCHTYPE);
		
		addNode(switchnode, _root);
		switchnode.getElement().addContent(switchname);
		switchnode.getElement().addContent(switchaddress);
		switchnode.getElement().addContent(switchport);
		switchnode.getElement().addContent(switchdescription);
		switchnode.getElement().addContent(switchcommunity);
		switchnode.getElement().addContent(switchtimeout);
		switchnode.getElement().addContent(switchmaxretries);
		switchnode.getElement().addContent(switchpducapacity);
		switchnode.getElement().addContent(switchtype);
		switchnode.getElement().addContent(switchportlist);
	}
	
	public void removeNode()
	{
		XMLTreeNode actNode = (XMLTreeNode)_jtree.getLastSelectedPathComponent();
		if (SWITCHNODE.equals(actNode.getElement().getName()))
		{
			removeNode(actNode);
		}
		else
		{
			removeNode((XMLTreeNode)actNode.getParent());
		}
	}
	
	private void changeNode(Element element, SwitchDataModel datamodel)
	{
		Element aspectElement;
		aspectElement = element.getChild(SWITCHNAME);
		aspectElement.setText(datamodel.getName());

		aspectElement = element.getChild(SWITCHADDRESS);
		aspectElement.setText(datamodel.getAddress());
		
		aspectElement = element.getChild(SWITCHPORT);
		aspectElement.setText(String.valueOf(datamodel.getPort()));

		aspectElement = element.getChild(SWITCHDESCRIPTION);
		aspectElement.setText(datamodel.getDescription());
		
		aspectElement = element.getChild(SWITCHCOMMUNITY);
		aspectElement.setText(datamodel.getCommunity());
		
		aspectElement = element.getChild(SWITCHTIMEOUT);
		aspectElement.setText(String.valueOf(datamodel.getTimeout()));
		
		aspectElement = element.getChild(SWITCHMAXRETRIES);
		aspectElement.setText(String.valueOf(datamodel.getMaxRetries()));
		
		aspectElement = element.getChild(SWITCHPDUCAPACITY);
		aspectElement.setText(String.valueOf(datamodel.getPDUCapacity()));

		aspectElement = element.getChild(SWITCHTYPE);
		aspectElement.setText(datamodel.getType());		
		
		aspectElement = element.getChild(SWITCHPORTCOUNT);
		aspectElement.removeContent();
		for(String port : datamodel.getPortList())
		{
			Element portelement = new Element(SWITCHIFPORT).setText(port);
			aspectElement.addContent(portelement);
		}
		
		
	}
	
	@SuppressWarnings("unchecked")
	public void changeSwitchNode(SwitchDataModel datamodel)
	{
		Iterator<Element> it = _root.getElement().getChildren(SWITCHNODE).iterator();
		while(it.hasNext())
		{
			Element element = it.next();
			if(element.getChildText(SWITCHNAME).equals(datamodel.getName()))
			{
				changeNode(element, datamodel);
				return;
			}
		}
	}
	
	public void changeCurrentNode(SwitchDataModel datamodel)
	{
		XMLTreeNode actNode = (XMLTreeNode)_jtree.getLastSelectedPathComponent();
		if(actNode.isRoot()) { return; }
		
		changeNode(actNode.getElement(), datamodel);
		
		actNode.setLabel(datamodel.getName());
		_treemodel.reload(actNode);
	}
}
